const dropZoneEl = document.getElementById("dropZone");
const listEl = document.querySelector(".file-list");
const currentPathEl = document.getElementById("currentPath");
const mp3PlayerEl = document.getElementById("mp3_player");
const progressWrapperEl = document.getElementById("processBarWrapper");
const loadingEl = document.getElementById("loading");
const uploader = new Uploader({});
const uploadInput = document.getElementById("up-files");
const audioTypes = new Set(["mp3", "wav", 'flac', 'ogg']);
const videoTypes = new Set(["mp4", "webm", "mkv", "mov", "avi"]);
let prevPlayBtnEl = null;
let maxcount = -1;
// Sorting State
let currentSortKey = 'file'; // 'file', 'size', 'time'
let currentSortOrder = 'asc'; // 'asc', 'desc'

let currentFileList = []; // Store list for re-sorting
let isGridView = localStorage.getItem('viewMode') === 'grid'; // Toggle state
const preview = new Preview();
preview.onPlayAudio = (btn, filePath) => handlePlayOrPause(btn, filePath);
preview.onInitAudioButton = (btn, filePath) => {
  if (!mp3PlayerEl.paused && mp3PlayerEl.dataset.filepath === filePath) {
    showPauseIcon(btn);
    prevPlayBtnEl = btn;
  }
};

// Video Player Elements
const videoContainer = document.getElementById('video-container');
const videoPlayer = document.getElementById('video-player');
const closeVideoBtn = document.getElementById('close-video');

// Initialize button text
document.getElementById("toggle-view-btn").textContent = isGridView ? "列表视图/List" : "预览视图/Preview";

const showLoading = () => {
  loadingEl.style.display = "block";
  dropZoneEl.style.display = "none";
};
const hideLoading = () => {
  loadingEl.style.display = "none";
  dropZoneEl.style.display = "block";
};

const updateProgress = (processBars, index, percent, loaded = 0, total = 0) => {
  const barEl = processBars[index];
  const numEl = barEl.querySelector(`#processBarNum${index}`);
  numEl.textContent = `${formatFileSize(loaded)} / ${formatFileSize(total)} = ${percent}%`;
  const innerBar = barEl.children[0];
  innerBar.style.width = `${percent}%`;
  if (percent === 100) innerBar.style.backgroundColor = "#abfaab";
};

const createProcessBars = (files) => {
  progressWrapperEl.innerHTML = "";
  return files.map((file, i) => {
    const wrapper = el('div', { class: 'process-bar-item', id: `processbar${i}` }, [
      el('div', { class: 'process-bar-inner' }),
      el('div', { class: 'process-bar-fileinfo' }, [
        el('span', { class: 'bar-filename' }, file.name),
        el('span', { class: 'num-info', id: `processBarNum${i}` }, ''),
      ]),
    ]);
    progressWrapperEl.appendChild(wrapper);
    return wrapper;
  });
};

const sortFiles = (files) => {
  return files.sort((a, b) => {
    let valA = a[currentSortKey === 'file' ? 'file' : currentSortKey === 'size' ? 'fileSize' : 'fileModifiedTime'];
    let valB = b[currentSortKey === 'file' ? 'file' : currentSortKey === 'size' ? 'fileSize' : 'fileModifiedTime'];

    // Handle directory vs file (directories always on top)
    if (a.fileType === '/' && b.fileType !== '/') return -1;
    if (a.fileType !== '/' && b.fileType === '/') return 1;

    if (currentSortKey === 'size') {
      valA = Number(valA);
      valB = Number(valB);
    }

    if (valA < valB) return currentSortOrder === 'asc' ? -1 : 1;
    if (valA > valB) return currentSortOrder === 'asc' ? 1 : -1;
    return 0;
  });
};

const updateSortHeaders = () => {
  document.querySelectorAll('.header-item').forEach(item => {
    item.classList.remove('asc', 'desc');
    if (item.dataset.sort === currentSortKey) {
      item.classList.add(currentSortOrder);
    }
  });

  document.querySelectorAll('.sort-btn').forEach(btn => {
    btn.classList.remove('active', 'asc', 'desc');
    if (btn.dataset.sort === currentSortKey) {
      btn.classList.add('active', currentSortOrder);
    }
  });
};

const handleSortClick = (sortKey) => {
  if (currentSortKey === sortKey) {
    currentSortOrder = currentSortOrder === 'asc' ? 'desc' : 'asc';
  } else {
    currentSortKey = sortKey;
    currentSortOrder = 'asc'; // Default to asc for new key
  }
  updateSortHeaders();
  renderFileList(currentFileList);
};

document.querySelectorAll('.header-item[data-sort]').forEach(header => {
  header.addEventListener('click', () => handleSortClick(header.dataset.sort));
});

document.querySelectorAll('.sort-btn').forEach(btn => {
  btn.addEventListener('click', () => handleSortClick(btn.dataset.sort));
});

const renderFileList = (files) => {
  const sortedFiles = sortFiles([...files]); // Sort a copy

  if (isGridView) {
    preview.renderGrid(sortedFiles, listEl);
  } else {
    listEl.className = 'file-list';

    const html = el('div', { class: 'dirlist', id: 'dirlist' }, sortedFiles
      .map(({ filePath, file, fileType, fileSize, fileModifiedTime, error }) => {
        const timeCol = el('div', { class: `col3 ${error ? "error" : ""}` }, fileModifiedTime);
        const delCol = el('div', { class: 'col_del' }, fileType === "/" ? "" : delBtnHTML);

        const ft = fileType ? fileType.toLowerCase() : "";
        let playColContent = "";
        if (audioTypes.has(ft)) {
          playColContent = playPauseBtnHTML;
        } else if (videoTypes.has(ft)) {
          playColContent = playPauseBtnHTML; // Use same icon for video
        }
        const playCol = el('div', { class: 'col_play_pause', 'data-filepath': filePath, 'data-type': ft }, playColContent);

        const sizeCol = el('div', { class: 'col2' }, ft === "/" ? "-" : formatFileSize(fileSize));

        const nameCol = error ? el('div', { class: 'error' }, `${file}${ft}`) : el('a', { title: file, href: filePath }, `${file}${ft === '/' ? '/' : ''}`);

        if (innerWidth > 640) {
          return el('div', { class: 'diritem' }, [el('div', { class: 'col1' }, nameCol), sizeCol, timeCol, playCol, delCol]);
        }
        return el('div', { class: 'diritem' }, [el('div', { class: 'col1' }, nameCol), el('div', { class: 'fileinfo' }, [sizeCol, timeCol, playCol, delCol])]);
      }))

    listEl.innerHTML = "";
    listEl.appendChild(html);
    if (sortedFiles.length === 0) {
      listEl.innerHTML = "";
      listEl.appendChild(el('p', { style: 'text-align:center; color:#555; padding: 20px;' }, '当前目录为空/The directory is empty'));
      return;
    }
  }

  // Attach delete listeners (Only for list view, grid view handles it internally)
  if (!isGridView) {
    listEl.querySelectorAll(".col_del").forEach((col, i) => {
      if (sortedFiles[i].fileType === "/") return;
      const btn = col.querySelector(".del_btn");
      btn.onclick = () => handleDelete(sortedFiles[i].filePath);
    });
  }

  // Attach play/pause listeners (For both views)
  const pausePlayBtnList = listEl.querySelectorAll(".col_play_pause");
  pausePlayBtnList.forEach((btnWrapper) => {
    const btn = btnWrapper.querySelector(".play_pause_btn");
    if (!btn) return;

    const filePath = btnWrapper.dataset.filepath;
    const fileType = btnWrapper.dataset.type;

    btn.onclick = (e) => {
      // Prevent grid item click
      e.stopPropagation();

      if (videoTypes.has(fileType)) {
        playVideo(filePath);
      } else {
        handlePlayOrPause(btn, filePath);
      }
    };
  });

  // Only restore state manually for List View.
  // Grid View handles this via preview.onInitAudioButton because elements are created asynchronously.
  if (!isGridView) {
    if (prevPlayBtnEl) {
      const currentSrc = mp3PlayerEl.dataset.filepath;
      // Find wrapper in either list view (.col_play_pause) or grid view (.play-overlay)
      const currentBtnWrapper = listEl.querySelector(`[data-filepath="${currentSrc}"]`);
      if (currentBtnWrapper) {
        currentPlayBtn = currentBtnWrapper.querySelector(".play_pause_btn")
        // Check if player is actually playing
        if (!mp3PlayerEl.paused) {
          showPauseIcon(currentPlayBtn);
        } else {
          showPlayIcon(currentPlayBtn);
        }
        prevPlayBtnEl = currentPlayBtn; // Update reference to the new button element
      } else {
        prevPlayBtnEl = null;
      }
    } else {
      // If prevPlayBtnEl was null, maybe we are reloading the page or something?
      // Try to recover state from audio player if it's playing
      if (!mp3PlayerEl.paused && mp3PlayerEl.dataset.filepath) {
        const currentSrc = mp3PlayerEl.dataset.filepath;
        const currentBtnWrapper = listEl.querySelector(`[data-filepath="${currentSrc}"]`);
        if (currentBtnWrapper) {
          const btn = currentBtnWrapper.querySelector(".play_pause_btn");
          showPauseIcon(btn);
          prevPlayBtnEl = btn;
        }
      }
    }
  }
};

const getStat = async () => {
  const rs = await (await fetch(`/list?pathname=${location.pathname}`)).json();
  if (rs.code === 500) {
    listEl.textContent = rs.error;
    dropZoneEl.style.visibility = "hidden";
    return;
  }
  dropZoneEl.style.visibility = "visible";
  currentPathEl.textContent = decodeURI(location.pathname);

  const ext = rs.ext;
  uploadInput.setAttribute("accept", ext)
  maxcount = rs.maxcount
  currentFileList = rs.list; // Store for sorting
  renderFileList(currentFileList);
};

const handleDelete = async (filePath) => {
  if (!confirm(`确认删除文件：${filePath} ？\r\nAre you sure you want to delete the file: ${filePath} ?`)) return;
  const res = await fetch(`/delete?filepath=${encodeURIComponent(filePath)}`, { method: "DELETE" });
  const json = await res.json();
  if (json.code === 200) {
    getStat();
  } else {
    alert(`文件删除失败！\n错误信息：${json.error}\r\nFile deletion failed!`);
  }
};

const showPlayIcon = (btn) => {
  const playIcon = btn.querySelector(".playIcon");
  const pauseIcon = btn.querySelector(".pauseIcon");
  playIcon.style.display = "block";
  pauseIcon.style.display = "none";
};

const showPauseIcon = (btn) => {
  const playIcon = btn.querySelector(".playIcon");
  const pauseIcon = btn.querySelector(".pauseIcon");
  playIcon.style.display = "none";
  pauseIcon.style.display = "block";
};

const handlePlayOrPause = (btn, filePath) => {
  const pauseIcon = btn.querySelector(".pauseIcon");
  const isPlaying = pauseIcon.style.display === "block";

  if (isPlaying) {
    showPlayIcon(btn);
    mp3PlayerEl.pause();
  } else {
    showPauseIcon(btn);
    if (!prevPlayBtnEl || prevPlayBtnEl !== btn) {
      mp3PlayerEl.src = filePath;
      mp3PlayerEl.setAttribute("data-filepath", filePath);
      prevPlayBtnEl && showPlayIcon(prevPlayBtnEl);
    }
    mp3PlayerEl.play();
    mp3PlayerEl.onended = () => {
      if (!prevPlayBtnEl) return;
      showPlayIcon(prevPlayBtnEl);
      prevPlayBtnEl = null;
    };
  }
  prevPlayBtnEl = btn;
};

// Video Player Logic
const playVideo = (src) => {
  videoPlayer.src = src;
  videoContainer.classList.add('active');
  videoPlayer.play();
};

closeVideoBtn.onclick = () => {
  videoContainer.classList.remove('active');
  videoPlayer.pause();
  videoPlayer.src = "";
};

const handlerFiles = async (files) => {
  if (!files || !files.length) return;
  if (maxcount && maxcount > -1 && currentFileList.length + files.length > maxcount) {
    alert(`当前${currentFileList.length}个文件，最多允许${maxcount}个文件，选中了${files.length}个文件，取消上传\r\nCurrently ${currentFileList.length} files, maximum allowed is ${maxcount}, selected ${files.length} files, upload cancelled`);
    return;
  }
  showLoading();
  let processCount = 0;
  const totalFiles = files.length;
  const processBars = createProcessBars(files);
  const timer = setInterval(getStat, 1000);

  await uploader.upload({
    url: location.pathname,
    data: files,
    error: ({ index }) => {
      processCount++;
      if (processCount === totalFiles) {
        clearInterval(timer);
        hideLoading();
        getStat();
      }
    },
    progress: (index, percent, loaded, total) => {
      updateProgress(processBars, index, percent, loaded, total);
    },
    success: () => {
      processCount++;
      if (processCount === totalFiles) {
        clearInterval(timer);
        hideLoading();
        getStat();
      }
    },
  });
};

dropZoneEl.addEventListener("dragenter", e => e.preventDefault());
dropZoneEl.addEventListener("dragover", e => {
  e.preventDefault();
  dropZoneEl.classList.add('dragover');
});
dropZoneEl.addEventListener("dragleave", e => {
  e.preventDefault();
  dropZoneEl.classList.remove('dragover');
});

dropZoneEl.addEventListener("drop", async (e) => {
  e.preventDefault();
  dropZoneEl.classList.remove('dragover');
  const items = e.dataTransfer?.items;
  if (!items) return;
  const files = [];
  for (let i = 0; i < items.length; i++) {
    const item = items[i];
    if (item.kind === "file" && item.webkitGetAsEntry().isFile) {
      files.push(item.getAsFile());
    }
  }
  await handlerFiles(files);
});

document.getElementById("select-btn").onclick = () => document.getElementById("up-files").click();
document.getElementById("toggle-view-btn").onclick = () => {
  isGridView = !isGridView;
  localStorage.setItem('viewMode', isGridView ? 'grid' : 'list');
  renderFileList(currentFileList);
  document.getElementById("toggle-view-btn").textContent = isGridView ? "列表视图/List" : "预览视图/Preview";
};
uploadInput.onchange = function () {
  handlerFiles(Array.from(this.files));
};

window.addEventListener("load", getStat);
